/**
 * Copyright © 2014 TingerSure. All rights reserved.
 */
package org.sure.scomet.link;

import org.sure.scomet.link.callback.CallBack;
import org.sure.scomet.util.ConfigManager;
import org.sure.scomet.util.PageIdManager;
import org.sure.scomet.util.log.LogManager;
import org.sure.scomet.util.log.LogType;

public class ConnectionCenter {

	private static long maxWaitTime = 0;

	public static long getMaxWaitTime() {
		return maxWaitTime;
	}

	private static boolean autoCheck;

	public static void closeConnection(int id) {
		Connection conn = PageIdManager.getConnectionByID(id);
		if (conn == null) {
			return;
		}
		if (conn.getSend() != null) {
			synchronized (conn.getSend()) {
				conn.getSend().setMessage("c:");
				conn.notify();
			}
		}
		PageIdManager.returnPageID(id);
	}

	public static int addConnection(Connection conn) {
		if (null == conn) {
			throw new NullPointerException();
		}
		int pageId = PageIdManager.getPageID(conn);
		conn.setPageId(pageId);
		return pageId;
	}

	private static CallBack callBack;

	public static void check(Connection conn)
			throws ConnectionOutofMaxTimeException {
		if (conn == null) {
			throw new NullPointerException();
		}
		if (System.currentTimeMillis() - conn.getLastLink() > maxWaitTime) {
			conn.getSend().setMessage(null);
			synchronized (conn.getSend()) {
				conn.getSend().notify();
			}
			closeConnection(conn.getPageId());
			throw new ConnectionOutofMaxTimeException("time out");
		}
	}

	public static void destroy() {
		callBack = null;
		maxWaitTime = 0;
		autoCheck = false;
		synchronized (autoCheckObject) {
			autoCheckObject.notify();
		}
		autoCheckObject = null;

	}

	public static Connection getConnection(int pageId) {
		return PageIdManager.getConnectionByID(pageId);
	}

	private static Runnable autoCheckObject = null;

	public static void init() {
		try {
			callBack = (CallBack) (Class.forName(ConfigManager.getConfig(
					"call-back", "org.sure.scomet.test.CallBackTest"))
					.newInstance());
		} catch (Exception e) {
			callBack = null;
			LogManager.logException("call back object new instance error", e,
					LogType.fatal);
		}
		maxWaitTime = Long.parseLong(ConfigManager.getConfig("max-wait-time",
				Long.toString(30 * 60))) * 1000;
		autoCheck = true;
		autoCheckObject = new PageIdManager();
		new Thread(autoCheckObject).start();
	}

	public static boolean isAutoCheck() {
		return autoCheck;
	}

	public static CallBack getCallBack() {
		return callBack;
	}
}
